/*
This file is part of La Linea.

La Linea is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

La Linea is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with La Linea.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef DISPLAYWIDGET_H
#define DISPLAYWIDGET_H

#include "globals.h"

#include <QtOpenGL>
#include <QElapsedTimer>
#include <QGLWidget>

#include <sstream>
#include <iostream>

#include "Animation.h"
#include "CacheManager.h"
#include "FrameStencil.h"
#include "Font.h"
#include "FontManager.h"

class DisplayWidget : public QGLWidget
{
    Q_OBJECT

public:
	enum EditMode {EDIT_POINTS = 0, EDIT_STENCIL = 1};
	
protected:
	unsigned int _displayOptions;
	
	int _screenWidth;
	int _screenHeight;
	GLfloat _screenFormat;
	
	EditMode _editMode;
	
	Vector2f _translateScene;
	Vector2f _mouseLastPos;
	GLfloat _zoom;	
	
	Animation* _currentAnimation;
	Node *_selectedNode;
	std::vector<Node*> _selectedStencilNodes;
	
	QElapsedTimer _timerFPS; // Timer used to compute FPS
	unsigned int _FPStime;
	unsigned int _FPScount;
	unsigned int _FPSlastValue;
	QTimer *_timer; // Timer used to refresh openGL view
	
	Font *_displayFont;
	
	bool _isPlaying;
	bool _dragAndDrop;
	
	void displayGrid();
	void displayOSD();

protected slots:
	virtual void timeOutSlot();

signals:
	void nodeSelected(Node* n);
	void nodeUpdated();
	
public:
    explicit DisplayWidget(Animation* anim, QWidget *parent = 0);
    virtual void initializeGL();
    virtual void resizeGL(int width, int height);
    virtual void paintGL();
    virtual void keyPressEvent(QKeyEvent *keyEvent);
	virtual void wheelEvent (QWheelEvent *event);
	virtual void mouseMoveEvent (QMouseEvent *event);
	virtual void mousePressEvent (QMouseEvent * event);
	virtual void mouseReleaseEvent (QMouseEvent * event);
	
	virtual void setAnimation(Animation* anim);
	virtual void tooglePoints();
	virtual void toogleCurvePoints();
	virtual void toogleCurves();
	virtual void toogleBorder();
	virtual void toogleFinal();
	virtual void toogleBoundingBox();
	virtual void toogleGhost(); // Display / Hide the ghost
	virtual void toogleGrid(); // Display / Hide the grid
	virtual void tooglePlay(); // Play / Stop the animation
	
	virtual void insertFrameBegin(); // insert a new frame at the beginning
	virtual void insertFrameEnd(); // Insert a new frame at the end
	virtual void insertFrameBefore(); // Insert a new frame before the current one
	virtual void insertFrameAfter(); // Insert a new frame after the current one
	
	virtual void duplicateFrameBegin(); 
	virtual void duplicateFrameEnd();
	virtual void duplicateFrameBefore();
	virtual void duplicateFrameAfter();
	
	virtual void clearFrame(); // Clear the current frame
	virtual void removeFrame(); // Remove the current frame
	
	virtual void previousFrame(); // Go to the previous frame
	virtual void nextFrame(); // Go to the next frame
	virtual void increaseFrameDuration(); // Increase the frame duration
	virtual void decreaseFrameDuration(); // Decrease the frame duration
	
	virtual void unselect(); // Unselect node
	virtual void deleteSelectedNode(); // Remove the selected node
	
	virtual void setEditPointsMode();
	virtual void setEditStencilMode();
	
	virtual void setBackgroundColor(GLfloat r, GLfloat g, GLfloat b);
	virtual void toogleOSD(); // Display / Hide On-Screen Display
	
	virtual void confirmPosStencil(); // Add the selected positive stencil to the animation
	virtual void confirmNegStencil(); // Add the selected negative stencil to the animation
	virtual void toogleDebugStencil(); // Toogle debug mode for stencils
	virtual void deleteFrameStencils(); // Delete current frame's stencils
	
protected:
	FrameStencil* createStencil(); // Create a stencil using selected nodes
};

#endif